##
## calcVotes
##
## written to calculate the overall ward percentages for each candidate.
## and then convert this into Processing code, because this info doesn't
## seem to be available in CSV anywhere else and I'd rather spend time
## writing some simple code than hand-coding the results for > 120 candidates

## represents a candidate
class Candidate
    
    ## attributes
    attr_accessor :name, :race, :ward, :votes, :voteShare
    
    ## constructor
    def initialize(n, r, w, v)
        @name = n
        @race = r
        @ward = w
        @votes = v.to_i
        @voteShare = 0
    end
    
    ## method to add votes
    def addVotes(v)
        @votes += v.to_i
    end
    
end ## class

## represents a ward
class Ward
    
    ## attributes
    attr_accessor :candidates, :race, :votes, :name
    
    ## constructor
    def initialize(n, r, c)
        
        @name = n
        @race = r
        
        @candidates = []
        @candidates.push(c)
        @votes = 0
        @votes += c.votes
    end
    
    ## method to add candidate
    def addCandidate(c)
        
        @candidates.push(c)
        @votes += c.votes
    end
    
end ## ward
    
## represents a race
class Race
    
    ## attributes
    attr_accessor :name, :wards
    
    ## constructor
    def initialize(n, w)
        
        @name = n
        @wards = []
        @wards.push(w)
    end
    
    ## method to add ward
    def addWard(w)
        @wards.push(w)
    end
    
end

## read results csv
f = File.new("/Users/macuser/Desktop/2010_Election_Final_Results.csv")
lines = f.readlines;
f.close

## declare variables
candidates = []
hasCandidate = false;
name = ""
ward = ""
race = ""
votes = 0
canIndex = 0

# iterate through results CSV and populate candidates array

lines.each_index { |j|
    
    ## skip header line
    if(j == 0)
        next
    end
    
    hasCandidate = false;
    
    splitline = lines[j].split(',')
    
    name = splitline[10][1..-2] #[1..-2] strips quotes
    race = splitline[2][1..-2]
    ward = splitline[4][1..-2]
    votes = splitline[11]
    
    ## check if candidates array already has this candidate; if not, add it; if so, add votes
    candidates.each_index { |i|
        if((candidates[i].name == name) && (candidates[i].race == race) && (candidates[i].ward == ward))
            hasCandidate = true
            canIndex = i
        end
    } ## each
    
    if hasCandidate
        candidates[canIndex].addVotes(votes)
    else
        candidates.push(Candidate.new(name, race, ward, votes))
    end
        
} ## each

## iterate through candidates and create ward arrays
wards = []
hasWard = false
warIndex = 0

candidates.each { |can|
    
    hasWard = false
    
    wardName = can.ward
    race = can.race
            
    ## check if ward already created; if not, create ward; if so, add votes
    wards.each_index { |i|
        if(wards[i].name == wardName)
            hasWard = true
            warIndex = i
        end
    }
    
    if hasWard
        wards[warIndex].addCandidate(can)
    else
        wards.push(Ward.new(wardName, race, can))
    end
    
}

## iterate through wards and write output for processing  
out = "      if(ind == 1) {\n"
out += "        sumOut = \"Overall: 33.4\";\n"
out += "      } else if(ind == 2) {\n"
out += "        sumOut = \"Average: \" + nf(dMode.ave, 3, 1);\n"
out += "      } else if(ind == 3) {\n"
out += "        sumOut = \"Average: \" + nf(dMode.ave, 3, 1);\n"

dMode = 4

wards.each { |ward|
    
    ## iterate through each candidate, calculate vote share
    ## and write Processing output
    wCandidates = ward.candidates
    
    wCandidates.each { |can|
      
      ## skip over votes and under votes
      if((can.name == "Over Votes") || (can.name == "Under Votes"))
          can.voteShare = can.votes.to_f / ward.votes.to_f * 100
          next
      end
      
      ## write Processing code, checking for acclamations
      if((can.name == "Dave Colburn") || (can.name == "Catherine Ripley"))
          out += "      } else if(ind == #{dMode}) {\n"
          out += "        sumOut = \"Candidate acclaimed\";\n"
      else
          can.voteShare = can.votes.to_f / ward.votes.to_f * 100
          voteShareString = "%.1f" % can.voteShare
      
          out += "      } else if(ind == #{dMode}) {\n"
          out += "        sumOut = \"Overall: #{voteShareString}\";\n"
      end
        
      # iterate dMode
      dMode += 1
    }
} 

out += "      }\n"

## write output
fo = File.new("out.txt", 'w')
fo.write(out)
fo.close()

## check
out = ""
candidates.each { |can|
    out += "#{can.name}: #{can.voteShare}\n"
}

fo2 = File.new("outCheck.txt", 'w')
fo2.write(out)
fo2.close()
